package cn.stylefeng.guns.modular.service.impl;

import cn.stylefeng.guns.base.consts.ConstantsContext;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.modular.entity.Device;
import cn.stylefeng.guns.modular.entity.Plant;
import cn.stylefeng.guns.modular.entity.Workshop;
import cn.stylefeng.guns.modular.entity.responseVo.DeviceListResponseVo;
import cn.stylefeng.guns.modular.mapper.DeviceMapper;
import cn.stylefeng.guns.modular.mapper.PlantMapper;
import cn.stylefeng.guns.modular.mapper.WorkshopMapper;
import cn.stylefeng.guns.modular.service.IDeviceService;
import cn.stylefeng.guns.modular.util.IdWorker;
import cn.stylefeng.guns.modular.util.QRCodeUtil;
import cn.stylefeng.guns.modular.util.json.JsonUtils;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import com.alibaba.druid.support.json.JSONUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import com.obs.services.ObsClient;
import com.obs.services.model.PutObjectResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * 设备表 服务实现类
 * </p>
 *
 * @author XiangTianGe
 * @since 2020-04-13
 */
@Service
public class DeviceServiceImpl extends ServiceImpl<DeviceMapper, Device> implements IDeviceService {

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private WorkshopMapper workshopMapper;

    @Autowired
    private PlantMapper plantMapper;

    @Autowired
    private IdWorker idWorker;


    @Override
    public ModelAndView edit(Long deviceId) {

        return null;
    }

    @Override
    public LayuiPageInfo deviceList(String keyword, String deviceType, Integer qrcode, String beginTime, String endTime, Page page) {
        QueryWrapper<Device> wrapper = new QueryWrapper();
        if (!Strings.isNullOrEmpty(keyword)) {
            wrapper.like("device_name", keyword);
        }
        if (!Strings.isNullOrEmpty(deviceType)) {
            wrapper.eq("device_type", deviceType);
        }
        if (qrcode != null) {
            if (qrcode == 1) {
                wrapper.isNotNull("device_qrcode");
            } else if (qrcode == 2) {
                wrapper.isNull("device_qrcode");
            }
        }

        if (!Strings.isNullOrEmpty(beginTime) && !Strings.isNullOrEmpty(endTime)) {
            wrapper.between("DATE(created_at)", beginTime, endTime);
        }
        IPage<Device> iPage = deviceMapper.selectPage(page, wrapper);
        List<Device> records = iPage.getRecords();
        List<DeviceListResponseVo> listResponseVos = records.stream().map(f -> {
            // 获取车间
            Workshop workshop = workshopMapper.selectById(f.getWorkshopId());
            // 获取工厂
            Plant plant = plantMapper.selectById(workshop.getPlantId());
            DeviceListResponseVo deviceListResponseVo = DeviceListResponseVo.fromDeviceListResponseVo(f, plant.getPlantName(), workshop.getWorkshopName());
            return deviceListResponseVo;
        }).collect(Collectors.toList());

        return LayuiPageFactory.createPageInfo(iPage, listResponseVos);
    }

    @Override
    public ResponseData deviceAdd(Device device) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("device_num", device.getDeviceNum());
        Device deviceNum = deviceMapper.selectOne(qw);
        if (deviceNum != null) {
            return ResponseData.error("此设备编号已存在!");
        }
        device.setCreatedAt(new Date());
        device.setUpdatedAt(new Date());
        device.setDeviceId(idWorker.nextId());
        deviceMapper.insert(device);
        return ResponseData.success();
    }

    @Override
    public ResponseData deviceEdit(Device device) {
        device.setUpdatedAt(new Date());
        deviceMapper.updateById(device);
        return ResponseData.success();
    }

    @Override
    public ResponseData delete(Long deviceId) {
        deviceMapper.deleteById(deviceId);
        return ResponseData.success();
    }

    @Override
    public ModelAndView queryDetails(Long deviceId) {

        ModelAndView modelAndView = new ModelAndView();
        // 获取设备
        Device device = deviceMapper.selectById(deviceId);
        // 获取车间
        Workshop workshop = workshopMapper.selectById(device.getWorkshopId());
        // 获取工厂
        Plant plant = plantMapper.selectById(workshop.getPlantId());
        modelAndView.addObject("device", device);
        modelAndView.addObject("workshop", workshop);
        modelAndView.addObject("plant", plant);
        return modelAndView;
    }

    /**
     * 跳转新增
     */
    @Override
    public ModelAndView add() {
        ModelAndView modelAndView = new ModelAndView();
        List<Workshop> workshops = workshopMapper.selectList(null);
        StringBuffer workshop = new StringBuffer();
        workshops.forEach(f -> {
            Long plantId = f.getPlantId();
            Plant plant = plantMapper.selectById(plantId);
            workshop.append("<option value=" + f.getWorkshopId() + ">" + plant.getPlantName() + "-" + f.getWorkshopName() + "</option>");
        });
        modelAndView.addObject("workshop", workshop);
        return modelAndView;
    }


    /**
     * 生成二维码
     */
    @Override
    public ResponseData generateCode(Long deviceId) {

        // 设备信息
        Device device = deviceMapper.selectById(deviceId);
        String text = JsonUtils.toJson(device); // 二维码内容
        int width = 600; // 二维码图片宽度
        int height = 600; // 二维码图片高度
        String format = "jpg";// 二维码的图片格式
        Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");    // 内容所使用字符集编码
        String obsAk = ConstantsContext.getObsAk();
        String obsSk = ConstantsContext.getObsSk();
        String obsEndPoint = ConstantsContext.getObsEndPoint();
        /* 创建OBS客户端 */
        ObsClient obsClient = new ObsClient(obsAk, obsSk, obsEndPoint);
        try {
            BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
            // 生成二维码
            File outputFile = new File(System.getProperty("user.dir") + File.separator + "qrcode.jpg");
            QRCodeUtil.writeToFile(bitMatrix, format, outputFile);
            final String keySuffixWithSlash = "device-qrcode/";
            PutObjectResult putObjectResult = obsClient.putObject("wbs-bucket", keySuffixWithSlash + UUID.randomUUID(), outputFile);
            String objectUrl = putObjectResult.getObjectUrl();
            if (!Strings.isNullOrEmpty(objectUrl)) {
                Device edit = new Device();
                edit.setDeviceId(deviceId);
                edit.setDeviceQrcode(objectUrl);
                deviceMapper.updateById(edit);
            }
            return ResponseData.success(objectUrl);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                obsClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}
